package com.yxw.yxnet_cd_center.customer_service.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.nacos.shaded.com.google.common.base.Joiner;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yxw.yxnet_cd_center.common.constant.CommonConstant;
import com.yxw.yxnet_cd_center.common.dto.PageVO;
import com.yxw.yxnet_cd_center.common.exception.BaseException;
import com.yxw.yxnet_cd_center.customer_service.dto.*;
import com.yxw.yxnet_cd_center.customer_service.entity.*;
import com.yxw.yxnet_cd_center.customer_service.mapper.*;
import com.yxw.yxnet_cd_center.customer_service.service.FlockService;
import com.yxw.yxnet_cd_center.customer_service.service.WorkflowService;
import com.yxw.yxnet_cd_center.customer_service.utils.PageUtils;
import com.yxw.yxnet_cd_center.customer_service.utils.UserUtil;
import com.yxw.yxnet_cd_center.customer_service.vo.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 工作群管理
 * @author liuxin
 * @date 2023.09.17
 */
@Service
public class FlockServiceImpl extends ServiceImpl<FlockMapper, YxCsFlockEntity> implements FlockService {

    @Autowired
    private FlockMapper flockMapper;

    @Autowired
    private UserUtil userUtil;

    @Autowired
    private WorkflowService workflowService;

    @Autowired
    private UserMapper  userMapper;

    @Autowired
    private GroupMapper groupMapper;

    @Autowired
    private PortMapper  portMapper;

    @Autowired
    private DictMapper  dictMapper;


    @Autowired
    private YxCsFlockUserMapper yxCsFlockUserMapper;

    @Autowired
    private YxScFlowRuleUserMapper yxScFlowRuleUserMapper;

    @Autowired
    private YxCsFlowRuleMapper yxCsFlowRuleMapper;

    @Autowired
    private WorkflowMapper workflowMapper;



    /**
     * 工作组分群-设置群
     * @param dto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addFlock(FlockAddDTO dto) {
        //校验分群信息
        validataAddFlock(dto);
        List<FlockDTO> flockList = dto.getFlockList();
        for (FlockDTO flock :flockList) {
            //不做修改
            if(null!=flock.getId()){
                continue;
            }
            YxCsFlockEntity entity = new YxCsFlockEntity();
            BeanUtil.copyProperties(flock,entity);
            entity.setCreateId(userUtil.getLoginUserId());
            entity.setCreateName(userUtil.getLoginName());
            entity.setCreateTime(new Date());
            entity.setGroupId(dto.getGroupId());
            entity.setStatus(CommonConstant.ZERO);
            //端口名称
            YxCsPortEntity portEntity = portMapper.selectById(flock.getPortId());
            if(null!=portEntity){
                entity.setPortName(portEntity.getPortName());
                entity.setPortCode(portEntity.getPortCode());
            }
            //关联项目
            DictionaryVo proData = dictMapper.getDictDataById(flock.getProjectType());
            if(null!=proData){
                entity.setProjectTypeName(proData.getName());
            }
            //群主
            YxCsUserEntity leaderUser = userMapper.selectById(flock.getLeaderId());
            if(null!=leaderUser){
                entity.setLeaderName(leaderUser.getUserName());
            }
            //服务类型
            DictionaryVo serviceTypeData = dictMapper.getDictDataById(flock.getServiceType());
            if(null!=serviceTypeData){
                entity.setServiceTypeName(serviceTypeData.getName());
                entity.setServiceTypeCode(serviceTypeData.getCode());
            }
            baseMapper.insert(entity);
            //新增群成员
            flockMapper.addFlockUser(entity.getId(),flock.getUserIdList());
            //默认新增基础规则信息
            YxCsFlowRuleEntity yxCsFlowRuleEntity = new YxCsFlowRuleEntity();
            BeanUtil.copyProperties(entity,yxCsFlowRuleEntity);
            //查询基础分流规则
            DictQueryDTO dictQueryDTO = new DictQueryDTO();
            dictQueryDTO.setDictType("base_rule_type");
            List<DictionaryVo> dictDataByType = dictMapper.getDictDataByType(dictQueryDTO);
            if(null==dictDataByType || dictDataByType.isEmpty()){
                throw new BaseException("未查询到基础分流规则,请先配置");
            }
            yxCsFlowRuleEntity.setRuleType(dictDataByType.get(0).getId());
            yxCsFlowRuleEntity.setRuleTypeCode(dictDataByType.get(0).getCode());
            yxCsFlowRuleEntity.setRuleTypeName(dictDataByType.get(0).getName());
            yxCsFlowRuleEntity.setCreateTime(new Date());
            yxCsFlowRuleEntity.setStatus(CommonConstant.ZERO);
            yxCsFlowRuleEntity.setFlockId(entity.getId());
            //渠道
            YxCsGroupEntity yxCsGroupEntity = groupMapper.selectById(entity.getGroupId());
            if(null==yxCsGroupEntity){
                throw new BaseException("工作组查询失败");
            }
            yxCsFlowRuleEntity.setChannelId(yxCsGroupEntity.getChannelId());
            yxCsFlowRuleEntity.setChannelCode(yxCsGroupEntity.getChannelCode());
            yxCsFlowRuleEntity.setChannelName(yxCsGroupEntity.getChannelName());
            yxCsFlowRuleMapper.insert(yxCsFlowRuleEntity);
            workflowMapper.addFlowRuleUser(yxCsFlowRuleEntity.getId(),flock.getUserIdList());
        }
    }
    /**
     * 分流管理-群列表查询
     * @param dto
     * @return
     */
    @Override
    public PageVO<YxCsFlockVo> getFlockList(FlockQueryDTO dto) {
        Page<YxCsFlockVo> page = new Page<>(dto.getCurrPage(), dto.getPageSize());
        List<YxCsFlockVo> list=baseMapper.getFlockList(page,dto);
        return PageUtils.get(page,list);
    }

    /**
     * 分流管理-群启用/禁用
     * @param dto
     */
    @Override
    public void updateFlockStatusById(StatusUpdateDTO dto) {
        YxCsFlockEntity entity = flockMapper.selectById(dto.getBussId());
        if(null!=entity){
            //禁用校验是否存在相同规则+服务的启用群，有就不允许禁用
            if(CommonConstant.ONE==dto.getStatus()){
                LambdaQueryWrapper<YxCsFlockEntity> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(true,YxCsFlockEntity::getStatus,CommonConstant.ZERO)
                        .eq(true,YxCsFlockEntity::getPortId,entity.getPortId())
                        .eq(true,YxCsFlockEntity::getServiceType,entity.getServiceType())
                        .ne(true,YxCsFlockEntity::getId,entity.getId());
                List<YxCsFlockEntity> yxCsFlockEntities = baseMapper.selectList(queryWrapper);
                if(null==yxCsFlockEntities || yxCsFlockEntities.isEmpty()){
                    throw new BaseException("该群所属的服务类型【"+entity.getServiceTypeName()+"】、端口【"+entity.getPortName()+"】规则组合不存在于其他启用的群,不允许禁用");
                }
            }
            entity.setUpdateId(userUtil.getLoginUserId());
            entity.setUpdateName(userUtil.getLoginName());
            entity.setUpdateTime(new Date());
            entity.setStatus(dto.getStatus());
            flockMapper.updateById(entity);
        }else{
            throw new BaseException("未找到对应群信息");
        }
    }

    /**
     * 分流管理-设置分流规则
     * @param dto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addWorkflowRule(FlowRuleAddDTO dto) {
        //根据群消息查询渠道-端口-组
        YxCsFlowRuleEntity entity =flockMapper.getFlowRuleByFlockId(dto.getFlockId());
        workflowService.addWorkflowRule(entity,dto);
    }

    /**
     * 群成员移除/添加
     * @param dto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveFlockUser(FlockUserUpdateDTO dto) {
        List<Long> userIdList = dto.getUserIdList();
        StringBuffer sbf=new StringBuffer();
        //删除
        if(CommonConstant.ONE==dto.getStatus()){
            //查询群人员信息
            LambdaQueryWrapper<YxCsFlockUserEntity> queryWrapper = new LambdaQueryWrapper<>();
            List<YxCsFlockUserEntity> yxCsFlockUserEntities = yxCsFlockUserMapper.selectList(queryWrapper);
            if(null==yxCsFlockUserEntities || yxCsFlockUserEntities.isEmpty()){
                throw new BaseException("查询群成员异常");
            }
            if(dto.getUserIdList().size()==yxCsFlockUserEntities.size()){
                throw new BaseException("群成员不能全部移除,可禁用该群以后重新设置群");
            }
            //校验人员是否存分配规则没有启用的人接
            List<UserRuleVo> voList=yxCsFlowRuleMapper.getNoUserRuleByIds(dto.getUserIdList());
            if(null!=voList && !voList.isEmpty()){
                for (UserRuleVo vo :voList) {
                    sbf.append("人员【"+vo.getUserName()+"】在渠道【"+vo.getChannelName()+"】、端口【"+vo.getPortName()+"】、服务类型【"+vo.getServiceTypeName()+"】、规则【"+vo.getRuleTypeName()+"】下没有其余启用人员接收,不能修改删除<br>");
                }
            }
            LambdaUpdateWrapper<YxCsFlockUserEntity> flockUserWrapper = new LambdaUpdateWrapper<>();
            flockUserWrapper.eq(true,YxCsFlockUserEntity::getFlockId,dto.getFlockId())
                    .in(true,YxCsFlockUserEntity::getUserId,userIdList);
            yxCsFlockUserMapper.delete(flockUserWrapper);
            //删除分流规则下面的人员
            yxScFlowRuleUserMapper.deleteUserByUserId(dto.getFlockId(),userIdList);
        }else if(CommonConstant.ZERO==dto.getStatus()){//新增
            //新增群聊人员
            flockMapper.addFlockUser(dto.getFlockId(),userIdList);
        }else{
            throw new BaseException("操作群状态错误");
        }
    }

    /**
     * 工作群群主转移
     * @param dto
     */
    @Override
    public void updateFlockLeader(FlockLeaderUpdateDTO dto) {
        //查询群信息
        YxCsFlockEntity entity = baseMapper.selectById(dto.getFlockId());
        if(null!=entity){
            entity.setLeaderId(dto.getLeaderId());
            entity.setLeaderName(dto.getLeaderName());
            baseMapper.updateById(entity);
        }else{
            throw new BaseException("群主移交失败：未找到对应群信息");
        }
    }

    /**
     * 查询群详情
     * @param flockId
     * @return
     */
    @Override
    public YxCsFlockVo getFlockById(Long flockId) {
        YxCsFlockEntity entity = baseMapper.selectById(flockId);
        YxCsFlockVo vo = new YxCsFlockVo();
        if(null!=entity){
            BeanUtil.copyProperties(entity,vo);
        }
        return vo;
    }

    /**
     * 工作组分群-设置群详情页查询群列表
     * @param groupId
     * @return
     */
    @Override
    public List<FlockDTO> getFlockListByAddFlock(Long groupId) {
        List<FlockDTO> flockDtoList=new ArrayList<>();
       //查询群列表
        LambdaQueryWrapper<YxCsFlockEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(true,YxCsFlockEntity::getGroupId,groupId)
                     .eq(true,YxCsFlockEntity::getStatus,CommonConstant.ZERO).orderByDesc(YxCsFlockEntity::getCreateTime);
        List<YxCsFlockEntity> yxCsFlockEntities = baseMapper.selectList(queryWrapper);
        if(null!=yxCsFlockEntities && !yxCsFlockEntities.isEmpty()){
            flockDtoList=BeanUtil.copyToList(yxCsFlockEntities,FlockDTO.class);
            for (FlockDTO flockDTO:flockDtoList) {
                //查询管理员
                YxCsUserEntity yxCsUserEntity = userMapper.selectById(flockDTO.getLeaderId());
                if(null!=yxCsUserEntity){
                    flockDTO.setLeaderName(yxCsUserEntity.getUserName());
                }
                LambdaQueryWrapper<YxCsFlockUserEntity> userWrapper = new LambdaQueryWrapper<>();
                userWrapper.eq(true,YxCsFlockUserEntity::getFlockId,flockDTO.getId());
                List<YxCsFlockUserEntity> yxCsFlockUserEntities = yxCsFlockUserMapper.selectList(userWrapper);
                if(null!=yxCsFlockUserEntities && !yxCsFlockUserEntities.isEmpty()){
                    //查询人员信息
                    flockDTO.setUserIdList(yxCsFlockUserEntities.stream().map(user->user.getUserId()).collect(Collectors.toList()));
                }
            }
        }
        return flockDtoList;
    }

    /**
     * 分流管理-设置分流规则规则查询
     * @param dto
     * @return
     */
    @Override
    public List<FlowRuleVo> getWorkflowRuleList(FlowRuleQueryDTO dto) {
        List<FlowRuleVo> voList=new ArrayList<>();
        Long flockId = dto.getFlockId();
        //查询规则大类
        DictQueryDTO dictQuery =new DictQueryDTO();
        dictQuery.setDictType("workfolw_type");
        List<DictionaryVo> dictDataByTypeList = dictMapper.getDictDataByType(dictQuery);
        for (DictionaryVo dictVo: dictDataByTypeList) {
            //规则大类查询小类
            dictQuery.setDictType(dictVo.getCode());
            List<DictionaryVo> ruleTypeList = dictMapper.getDictDataByType(dictQuery);
            //查询分类对应的有效规则
            //查询对应分流规则
            LambdaQueryWrapper<YxCsFlowRuleEntity> queryWrapper = new LambdaQueryWrapper<>();
            List<Long> ruleTypes = ruleTypeList.stream().map(rule -> rule.getId()).collect(Collectors.toList());
            queryWrapper.eq(true,YxCsFlowRuleEntity::getFlockId,flockId).eq(true,YxCsFlowRuleEntity::getStatus,CommonConstant.ZERO)
            .in(true,YxCsFlowRuleEntity::getRuleType,ruleTypes).orderByAsc(YxCsFlowRuleEntity::getRuleType);
            List<YxCsFlowRuleEntity> yxCsFlowRuleEntities = yxCsFlowRuleMapper.selectList(queryWrapper);
            FlowRuleVo vo = new FlowRuleVo();
            if(null!=yxCsFlowRuleEntities && !yxCsFlowRuleEntities.isEmpty()){
                vo.setFlockId(yxCsFlowRuleEntities.get(0).getFlockId());
                vo.setFirstRuleType(dictVo.getId());
                List<FlowRuleFitDTO> ruleFitList=new ArrayList<>();
                for (int i = 0; i < yxCsFlowRuleEntities.size(); i++) {
                    YxCsFlowRuleEntity yxCsFlowRuleEntity = yxCsFlowRuleEntities.get(i);
                    FlowRuleFitDTO fitDTO = new FlowRuleFitDTO();
                    fitDTO.setRuleType(yxCsFlowRuleEntity.getRuleType());
                    fitDTO.setRuleId(yxCsFlowRuleEntity.getId());
                    //查询规则人员
                    LambdaQueryWrapper<YxScFlowRuleUserEntity> ruleUserWrapper = new LambdaQueryWrapper<>();
                    ruleUserWrapper.eq(true,YxScFlowRuleUserEntity::getFlowRuleId,yxCsFlowRuleEntity.getId());
                    List<YxScFlowRuleUserEntity> yxScFlowRuleUserEntities = yxScFlowRuleUserMapper.selectList(ruleUserWrapper);
                    if(null!=yxScFlowRuleUserEntities && !yxScFlowRuleUserEntities.isEmpty()){
                        List<Long> userIdList = yxScFlowRuleUserEntities.stream().map(user -> user.getUserId()).collect(Collectors.toList());
                        fitDTO.setUserIdList(userIdList);
                    }
                    ruleFitList.add(fitDTO);
                }
                vo.setFitList(ruleFitList);
                voList.add(vo);
            }
        }
        return voList;
    }

    //-------------------------------------------------------------------------------------------------------------------------------

    /**
     * 校验分群信息
     * 1：按照服务类型和端口一次性分完群
     * 2：同一个人不能分配到相同服务类型+相同端口的群
     * 3：群名称不能重复
     * @param dto
     */
    private void validataAddFlock(FlockAddDTO dto) {
        StringBuffer sbf = new StringBuffer();
        //查询工作组
        YxCsGroupEntity groupEntity = groupMapper.selectById(dto.getGroupId());
        if (null == groupEntity) {
            throw new BaseException("群对应工作组不存在");
        }
        DictQueryDTO dictQueryDTO = new DictQueryDTO();
        dictQueryDTO.setDictType("service_type");
        dictQueryDTO.setStatus(0);
        List<DictionaryVo> serviceTypeList = dictMapper.getDictDataByType(dictQueryDTO);
        //查询渠道下面对应的所有端口
        List<PortVo> portList = portMapper.getPortList(groupEntity.getChannelId());
        if(null==serviceTypeList || serviceTypeList.isEmpty() || null==portList || portList.isEmpty()){
            throw  new BaseException("未查询到对应服务类型/端口");
        }
        //根据服务类型和端口重组集合
        List<FlockDTO> flockList = dto.getFlockList();
        //全量组合数据
        List<String> ruleList =flockList.stream().map(a -> a.getServiceType() + "_" + a.getPortId()).collect(Collectors.toList());
        /**
         * 1：按照服务类型和端口一次性分完群
         */
        for (int i = 0; i < serviceTypeList.size(); i++) {
            Long serviceType = serviceTypeList.get(i).getId();
            String serviceTypeName = serviceTypeList.get(i).getName();
            for (int j = 0; j < portList.size(); j++) {
                Long portId = portList.get(j).getPortId();
                String portName = portList.get(j).getPortName();
                if (!ruleList.contains(serviceType + "_" + portId)) {
                    sbf.append("服务类型为【" + serviceTypeName + "】加端口为【" + portName + "】的组合还未分配<br>");
                }
            }
        }
        /**
         * 2：同一个人不能分配到相同服务类型+相同端口的群
         */
        //重复组合的数据
//        List<String> ruleRepeatList = ruleList.stream() .filter( t1 -> ruleList.stream().filter(t2 -> t1.equals(t2)).count() >1).collect(Collectors.toList()).stream().distinct().collect(Collectors.toList());
//        for (String rule: ruleRepeatList) {
//            String[] split = rule.split("_");
//            Long s=Long.valueOf(split[0]);//服务类型
//            Long p=Long.valueOf(split[1]);//端口
//            //找到重复组合数据
//            List<FlockDTO> flockRepeatList= flockList.stream().filter((FlockDTO f) ->f.getPortId().compareTo(p)==0 && f.getServiceType().compareTo(s)==0).collect(Collectors.toList());
//            //判断重复
//            List<Long> userIdList =new ArrayList<>();
//            for (FlockDTO flockDto:flockRepeatList) {
//                userIdList.addAll(flockDto.getUserIdList());
//            }
//            List<Long> repeatUserIds = userIdList.stream().filter(t1 -> userIdList.stream().filter(t2 -> t1.equals(t2)).count() >1).collect(Collectors.toList()).stream().distinct().collect(Collectors.toList());
//            if(null!=repeatUserIds && !repeatUserIds.isEmpty()){
//                String pName=portList.stream().filter(port -> port.getPortId().compareTo(p)==0).collect(Collectors.toList()).get(0).getPortName();
//                String sName=serviceTypeList.stream().filter(server -> server.getId().compareTo(s)==0).collect(Collectors.toList()).get(0).getName();
//                sbf.append("服务类型为【" + sName + "】加端口为【" + pName+ "】的组合分配了相同人员<br>");
//            }
//        }
        /**
         * 3:名重复校验
         */
        List<String> flockNames =flockList .stream().map(a -> a.getFlockName()).collect(Collectors.toList());
        List<String> repeatflockNames = flockNames.stream() .filter( t1 -> flockNames.stream().filter(t2 -> t1.equals(t2)).count() >1).collect(Collectors.toList()).stream().distinct().collect(Collectors.toList());
        if(null!=repeatflockNames && !repeatflockNames.isEmpty()){
            sbf.append("群【"+ Joiner.on(",").join(repeatflockNames)+"】名称重复<br>");
        }
        /**
         * 群主必须在群里面
         */
        for (int i = 0; i < flockList.size(); i++) {
            FlockDTO flockDTO = flockList.get(i);
            List<Long> userIdList = flockDTO.getUserIdList();
            if(!userIdList.contains(flockDTO.getLeaderId())){
                sbf.append("群【"+flockDTO.getFlockName()+"】未将群主添加到群成员里面<br>");
            }
        }
        if(StringUtils.isNotBlank(sbf.toString())){
            throw  new BaseException(sbf.toString());
        }
    }
}
